/*  
 * Actipro Software's WPF DataGrid / Editors Integration Add-on
 * http://actipro.codeplex.com/
 * 
 * Copyright (c) 2009-2015 Actipro Software LLC. 
 *  
 * This source code is subject to the terms of the Microsoft Public License (Ms-PL). 
 *  
 * Redistribution and use in source and binary forms, with or without modification, 
 * is permitted provided that redistributions of the source code retain the above 
 * copyright notices and this file header. 
 *  
 * Additional copyright notices should be appended to the list above. 
 * 
 * For details, see <http://www.opensource.org/licenses/ms-pl.html>. 
 *  
 * All other rights reserved. 
 *
 */  


using System;
using System.Diagnostics.CodeAnalysis;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;

namespace ActiproSoftware.Windows.Controls.Editors.Interop.DataGrid.Primitives {

	/// <summary>
	/// Represents a base class for data-bound columns for use in a <c>DataGrid</c> that utilizes <see cref="PartEditBox"/>-derived controls.
	/// </summary>
	public abstract class DataGridPartEditBoxColumnBase : DataGridBoundColumnBase {

		private static Style defaultElementStyle;
		private static Style defaultEditingElementStyle;

		#region Dependency Properties

		/// <summary>
		/// Identifies the <see cref="CenterSlotHorizontalAlignment"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="CenterSlotHorizontalAlignment"/> dependency property.</value>
		public static readonly DependencyProperty CenterSlotHorizontalAlignmentProperty = PartEditBox.CenterSlotHorizontalAlignmentProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(HorizontalAlignment.Stretch, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="CenterSlotMargin"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="CenterSlotMargin"/> dependency property.</value>
		public static readonly DependencyProperty CenterSlotMarginProperty = PartEditBox.CenterSlotMarginProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(new Thickness(0), OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="CheckBoxVisibility"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="CheckBoxVisibility"/> dependency property.</value>
		public static readonly DependencyProperty CheckBoxVisibilityProperty = PartEditBox.CheckBoxVisibilityProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(Visibility.Collapsed, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="DropDownButtonVisibility"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="DropDownButtonVisibility"/> dependency property.</value>
		public static readonly DependencyProperty DropDownButtonVisibilityProperty = PartEditBox.DropDownButtonVisibilityProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(Visibility.Collapsed, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="IsHintTransitioningEnabled"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="IsHintTransitioningEnabled"/> dependency property.</value>
		public static readonly DependencyProperty IsHintTransitioningEnabledProperty = PartEditBox.IsHintTransitioningEnabledProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(true, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="LeftSlotMargin"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="LeftSlotMargin"/> dependency property.</value>
		public static readonly DependencyProperty LeftSlotMarginProperty = PartEditBox.LeftSlotMarginProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(new Thickness(0, 0, 3, 0), OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="MaxDropDownHeight"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="MaxDropDownHeight"/> dependency property.</value>
		public static readonly DependencyProperty MaxDropDownHeightProperty = PartEditBox.MaxDropDownHeightProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(SystemParameters.PrimaryScreenHeight / 3.0, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="MaxDropDownWidth"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="MaxDropDownWidth"/> dependency property.</value>
		public static readonly DependencyProperty MaxDropDownWidthProperty = PartEditBox.MaxDropDownWidthProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(double.NaN, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="MinDropDownHeight"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="MinDropDownHeight"/> dependency property.</value>
		public static readonly DependencyProperty MinDropDownHeightProperty = PartEditBox.MinDropDownHeightProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(0.0, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="MinDropDownWidth"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="MinDropDownWidth"/> dependency property.</value>
		public static readonly DependencyProperty MinDropDownWidthProperty = PartEditBox.MinDropDownWidthProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(double.NaN, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="RightSlotMargin"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="RightSlotMargin"/> dependency property.</value>
		public static readonly DependencyProperty RightSlotMarginProperty = PartEditBox.RightSlotMarginProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(new Thickness(3, 0, 0, 0), OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="SpinBehavior"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="SpinBehavior"/> dependency property.</value>
		public static readonly DependencyProperty SpinBehaviorProperty = PartEditBox.SpinBehaviorProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(SpinBehavior.NoWrap, OnNotifyablePropertyValueChanged));

		/// <summary>
		/// Identifies the <see cref="SpinnerVisibility"/> dependency property.  This field is read-only.
		/// </summary>
		/// <value>The identifier for the <see cref="SpinnerVisibility"/> dependency property.</value>
		public static readonly DependencyProperty SpinnerVisibilityProperty = PartEditBox.SpinnerVisibilityProperty.AddOwner(typeof(DataGridPartEditBoxColumnBase),
			new FrameworkPropertyMetadata(Visibility.Collapsed, OnNotifyablePropertyValueChanged));

		#endregion // Dependency Properties

		/////////////////////////////////////////////////////////////////////////////////////////////////////
		#region OBJECT
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		/// <summary>
		/// Initializes the <see cref="DataGridPartEditBoxColumnBase"/> class.
		/// </summary>
		[SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
		static DataGridPartEditBoxColumnBase() {
			DataGridBoundColumn.EditingElementStyleProperty.OverrideMetadata(typeof(DataGridPartEditBoxColumnBase),
				new FrameworkPropertyMetadata(DefaultEditingElementStyle));
			DataGridBoundColumn.ElementStyleProperty.OverrideMetadata(typeof(DataGridPartEditBoxColumnBase),
				new FrameworkPropertyMetadata(DefaultElementStyle));
		}

		#endregion // OBJECT

		/////////////////////////////////////////////////////////////////////////////////////////////////////
		#region PUBLIC PROCEDURES
		/////////////////////////////////////////////////////////////////////////////////////////////////////

		/// <summary>
		/// Applies standard values to the specified target element.
		/// </summary>
		/// <param name="targetElement">The target element.</param>
		protected override void ApplyStandardValues(FrameworkElement targetElement) {
			if (targetElement is PartEditBox) {
				this.ApplyValue(CenterSlotHorizontalAlignmentProperty, targetElement, PartEditBox.CenterSlotHorizontalAlignmentProperty);
				this.ApplyValue(CenterSlotMarginProperty, targetElement, PartEditBox.CenterSlotMarginProperty);
				this.ApplyValue(CheckBoxVisibilityProperty, targetElement, PartEditBox.CheckBoxVisibilityProperty);
				this.ApplyValue(DropDownButtonVisibilityProperty, targetElement, PartEditBox.DropDownButtonVisibilityProperty);
				this.ApplyValue(IsHintTransitioningEnabledProperty, targetElement, PartEditBox.IsHintTransitioningEnabledProperty);
				this.ApplyValue(LeftSlotMarginProperty, targetElement, PartEditBox.LeftSlotMarginProperty);
				this.ApplyValue(MaxDropDownHeightProperty, targetElement, PartEditBox.MaxDropDownHeightProperty);
				this.ApplyValue(MaxDropDownWidthProperty, targetElement, PartEditBox.MaxDropDownWidthProperty);
				this.ApplyValue(MinDropDownHeightProperty, targetElement, PartEditBox.MinDropDownHeightProperty);
				this.ApplyValue(MinDropDownWidthProperty, targetElement, PartEditBox.MinDropDownWidthProperty);
				this.ApplyValue(RightSlotMarginProperty, targetElement, PartEditBox.RightSlotMarginProperty);
				this.ApplyValue(SpinBehaviorProperty, targetElement, PartEditBox.SpinBehaviorProperty);
				this.ApplyValue(SpinnerVisibilityProperty, targetElement, PartEditBox.SpinnerVisibilityProperty);
			}
			base.ApplyStandardValues(targetElement);
		}

		/// <summary>
		/// Gets or sets the horizontal alignment used for the center slot container element of the associated <c>PartEditBox</c>.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The horizontal alignment used for the center slot container element of the associated <c>PartEditBox</c>.
		/// The default value is <c>HorizontalAlignment.Stretch</c>.
		/// </value>
		public HorizontalAlignment CenterSlotHorizontalAlignment {
			get { return (HorizontalAlignment)this.GetValue(DataGridPartEditBoxColumnBase.CenterSlotHorizontalAlignmentProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.CenterSlotHorizontalAlignmentProperty, value); }
		}

		/// <summary>
		/// Gets or sets the margin used for the center slot container element of the associated <c>PartEditBox</c>.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The margin used for the center slot container element of the associated <c>PartEditBox</c>.
		/// The default value is <c>0</c>.
		/// </value>
		public Thickness CenterSlotMargin {
			get { return (Thickness)this.GetValue(DataGridPartEditBoxColumnBase.CenterSlotMarginProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.CenterSlotMarginProperty, value); }
		}

		/// <summary>
		/// Gets or sets the <see cref="Visibility"/> of the <c>CheckBox</c> presented by the associated <c>PartEditBox</c>.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The <see cref="Visibility"/> of the <c>CheckBox</c> presented by the associated <c>PartEditBox</c>.
		/// The default value is <c>Visibility.Collapsed</c>.
		/// </value>
		public Visibility CheckBoxVisibility {
			get { return (Visibility)this.GetValue(DataGridPartEditBoxColumnBase.CheckBoxVisibilityProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.CheckBoxVisibilityProperty, value); }
		}

		/// <summary>
		/// Gets the default value for the <c>EditingElementStyleProperty</c> dependency property.
		/// </summary>
		/// <value>The default value for the <c>EditingElementStyleProperty</c> dependency property.</value>
		public static Style DefaultEditingElementStyle {
			get {
				if (defaultEditingElementStyle == null) {
					defaultEditingElementStyle = GenerateBaseStyle(typeof(PartEditBox), true);
					defaultEditingElementStyle.Seal();
				}
				return defaultEditingElementStyle;
			}
		}

		/// <summary>
		/// Gets the default value for the <c>EditingElementStyleProperty</c> dependency property.
		/// </summary>
		/// <value>The default value for the <c>EditingElementStyleProperty</c> dependency property.</value>
		public static Style DefaultElementStyle {
			get {
				if (defaultElementStyle == null) {
					defaultElementStyle = GenerateBaseStyle(typeof(PartEditBox), false);
					defaultElementStyle.Seal();
				}
				return defaultElementStyle;
			}
		}

		/// <summary>
		/// Gets or sets the <see cref="Visibility"/> of the <c>DropDownButton</c> presented by the associated <c>PartEditBox</c>.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The <see cref="Visibility"/> of the <c>DropDownButton</c> presented by the associated <c>PartEditBox</c>.
		/// The default value is <c>Visibility.Collapsed</c>.
		/// </value>
		public Visibility DropDownButtonVisibility {
			get { return (Visibility)this.GetValue(DataGridPartEditBoxColumnBase.DropDownButtonVisibilityProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.DropDownButtonVisibilityProperty, value); }
		}

		/// <summary>
		/// Generates a <see cref="Style"/> that can be used as the basis for the element styles.
		/// </summary>
		/// <param name="targetType">Type of the target.</param>
		/// <param name="isEditing">if set to <c>true</c> the style will be used for the editing element.</param>
		/// <returns>A <see cref="Style"/> that can be used as the basis for the element styles.</returns>
		protected static Style GenerateBaseStyle(Type targetType, bool isEditing) {
			Style style = new Style(targetType);
			style.Setters.Add(new Setter(PartEditBox.BorderThicknessProperty, new Thickness(0.0)));
			style.Setters.Add(new Setter(PartEditBox.PaddingProperty, new Thickness(0.0)));
			style.Setters.Add(new Setter(PartEditBox.MarginProperty, new Thickness(0.0)));
			style.Setters.Add(new Setter(PartEditBox.DropDownButtonMarginProperty, new Thickness(0.0)));
			style.Setters.Add(new Setter(PartEditBox.ForegroundProperty,
				new Binding("Foreground") {
					RelativeSource = new RelativeSource() { AncestorType = typeof(DataGridCell)
					}
				}));

			if (!isEditing) {
				style.Setters.Add(new Setter(PartEditBox.BackgroundProperty, Brushes.Transparent));
				style.Setters.Add(new Setter(PartEditBox.IsDropDownButtonTransparencyModeEnabledProperty, true));
				style.Setters.Add(new Setter(PartEditBox.IsHitTestVisibleProperty, false));
				style.Setters.Add(new Setter(PartEditBox.FocusableProperty, false));
			}

			return style;
		}

		/// <summary>
		/// Generates an instance of a <see cref="PartEditBox"/>-derived object.
		/// </summary>
		/// <param name="isEditing">if set to <c>true</c> the edit box will be used for editing.</param>
		/// <param name="cell">The cell.</param>
		/// <returns>An instance of a <see cref="PartEditBox"/>-derived object.</returns>
		protected abstract PartEditBox GenerateEditBox(bool isEditing, DataGridCell cell);

		/// <summary>
		/// Generates the editing element.
		/// </summary>
		/// <param name="cell">The cell.</param>
		/// <param name="dataItem">The data item.</param>
		/// <returns>The <c>FrameworkElement</c> to use for editing.</returns>
		protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem) {
			return this.GenerateEditBox(true, cell);
		}

		/// <summary>
		/// Generates the element.
		/// </summary>
		/// <param name="cell">The cell.</param>
		/// <param name="dataItem">The data item.</param>
		/// <returns>
		/// The <c>FrameworkElement</c> to use for display.
		/// </returns>
		protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem) {
			return this.GenerateEditBox(false, cell);
		}

		/// <summary>
		/// Gets the value associated with the specified <see cref="PartEditBox"/>.
		/// </summary>
		/// <param name="editBox">The <see cref="PartEditBox"/> whose value should be returned.</param>
		/// <returns>The value associated with the specified <see cref="PartEditBox"/>.</returns>
		protected abstract object GetEditBoxValue(PartEditBox editBox);

		/// <summary>
		/// Gets or sets a value indicating whether the hint will be animated to/from the regular content.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// <c>true</c> if the hint will be animated to/from the regular content; otherwise, <c>false</c>.
		/// The default value is <c>true</c>.
		/// </value>
		public bool IsHintTransitioningEnabled {
			get { return (bool)this.GetValue(DataGridPartEditBoxColumnBase.IsHintTransitioningEnabledProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.IsHintTransitioningEnabledProperty, value); }
		}

		/// <summary>
		/// Gets or sets the margin used for the left slot container element of the associated <c>PartEditBox</c>.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The margin used for the left slot container element of the associated <c>PartEditBox</c>.
		/// The default value is <c>0</c>.
		/// </value>
		public Thickness LeftSlotMargin {
			get { return (Thickness)this.GetValue(DataGridPartEditBoxColumnBase.LeftSlotMarginProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.LeftSlotMarginProperty, value); }
		}

		/// <summary>
		/// Gets or sets the maximum height of the drop-down popup.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The maximum height of the drop-down popup.
		/// The default value is <c>SystemParameters.PrimaryScreenHeight / 3.0</c>.
		/// </value>
		public double MaxDropDownHeight {
			get { return (double)this.GetValue(DataGridPartEditBoxColumnBase.MaxDropDownHeightProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.MaxDropDownHeightProperty, value); }
		}

		/// <summary>
		/// Gets or sets the maximum width of the drop-down popup.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The maximum width of the drop-down popup.
		/// The default value is <c>double.NaN</c>.
		/// </value>
		public double MaxDropDownWidth {
			get { return (double)this.GetValue(DataGridPartEditBoxColumnBase.MaxDropDownWidthProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.MaxDropDownWidthProperty, value); }
		}

		/// <summary>
		/// Gets or sets the minimum height of the drop-down popup.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The minimum height of the drop-down popup.
		/// The default value is <c>0.0</c>.
		/// </value>
		public double MinDropDownHeight {
			get { return (double)this.GetValue(DataGridPartEditBoxColumnBase.MinDropDownHeightProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.MinDropDownHeightProperty, value); }
		}

		/// <summary>
		/// Gets or sets the minimum width of the drop-down popup.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The minimum width of the drop-down popup.
		/// The default value is <c>double.NaN</c>.
		/// </value>
		public double MinDropDownWidth {
			get { return (double)this.GetValue(DataGridPartEditBoxColumnBase.MinDropDownWidthProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.MinDropDownWidthProperty, value); }
		}

		/// <summary>
		/// Prepares the cell for edit.
		/// </summary>
		/// <param name="editingElement">The editing element.</param>
		/// <param name="editingEventArgs">The <see cref="RoutedEventArgs"/> instance containing the event data.</param>
		/// <returns></returns>
		protected override object PrepareCellForEdit(FrameworkElement editingElement, RoutedEventArgs editingEventArgs) {
			PartEditBox editBox = editingElement as PartEditBox;
			if (null == editBox)
				return null;

			editBox.Focus();
			object uneditedValue = this.GetEditBoxValue(editBox);

			MouseButtonEventArgs mouseArgs = editingEventArgs as MouseButtonEventArgs;
			if (IsMouseLeftButtonDown(mouseArgs)) {
				// This variable will hold the ToggleButton that is found as part of the hit-testing, if any
				ToggleButton toggleButton = null;

				// Declare and implement the filter callback method, which looks for the last BreadcrumbButtonBase object
				HitTestFilterCallback filterCallback = new HitTestFilterCallback(delegate(DependencyObject target) {
					FrameworkElement element = target as FrameworkElement;
					if (null != element && element.IsVisible && element is ToggleButton) {
						toggleButton = target as ToggleButton;
						return HitTestFilterBehavior.Stop;
					}
					return HitTestFilterBehavior.Continue;
				});

				// Declare and implement the result callback method, which simply defaults to returning Stop. The real logic is in the
				//   filter callback above.
				HitTestResultCallback resultCallback = new HitTestResultCallback(delegate(HitTestResult result) {
					return HitTestResultBehavior.Stop;
				});

				// Perform the hit-testing starting with the Breadcrumb control
				VisualTreeHelper.HitTest(editBox, filterCallback, resultCallback, new PointHitTestParameters(mouseArgs.GetPosition(editBox)));

				// Toggle the IsChecked property, if it's a ToggleButton
				if (toggleButton != null)
					toggleButton.IsChecked = new bool?(toggleButton.IsChecked != true);
			}
			return uneditedValue;
		}

		/// <summary>
		/// Gets or sets the margin used for the right slot container element of the associated <c>PartEditBox</c>.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The margin used for the right slot container element of the associated <c>PartEditBox</c>.
		/// The default value is <c>0</c>.
		/// </value>
		public Thickness RightSlotMargin {
			get { return (Thickness)this.GetValue(DataGridPartEditBoxColumnBase.RightSlotMarginProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.RightSlotMarginProperty, value); }
		}

		/// <summary>
		/// Gets or sets the behavior used when spinning an associated value.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The behavior used when spinning an associated value.
		/// The default value is <c>SpinBehavior.NoWrap</c>.
		/// </value>
		public SpinBehavior SpinBehavior {
			get { return (SpinBehavior)this.GetValue(DataGridPartEditBoxColumnBase.SpinBehaviorProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.SpinBehaviorProperty, value); }
		}

		/// <summary>
		/// Gets or sets the <see cref="Visibility"/> of the <c>Spinner</c> presented by the associated <c>PartEditBox</c>.
		/// This is a dependency property.
		/// </summary>
		/// <value>
		/// The <see cref="Visibility"/> of the <c>Spinner</c> presented by the associated <c>PartEditBox</c>.
		/// The default value is <c>Visibility.Collapsed</c>.
		/// </value>
		public Visibility SpinnerVisibility {
			get { return (Visibility)this.GetValue(DataGridPartEditBoxColumnBase.SpinnerVisibilityProperty); }
			set { this.SetValue(DataGridPartEditBoxColumnBase.SpinnerVisibilityProperty, value); }
		}

		#endregion // PUBLIC PROCEDURES
	}
}
